package com.fsj.admin.system.controller;

import com.fsj.admin.common.annotation.Log;
import com.fsj.admin.common.config.Constant;
import com.fsj.admin.common.controller.BaseController;
import com.fsj.admin.common.domain.DictDO;
import com.fsj.admin.common.service.DictService;
import com.fsj.admin.common.utils.*;
import com.fsj.admin.system.domain.*;
import com.fsj.admin.system.service.*;
import com.fsj.admin.system.vo.InviteWaterVO;
import com.fsj.admin.system.vo.TUserInfoVO;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.*;

@RequestMapping("/sys/check")
@Controller
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = {RuntimeException.class, Exception.class})
public class CheckController extends BaseController {
    private Logger logger = LoggerFactory.getLogger(CheckController.class);

    String prefix = "system";
    @Autowired
    TUserService tUserService;
    @Autowired
    IdentityInfoService identityInfoService;
    @Autowired
    WalletService walletService;
    @Autowired
    CashRecordService cashRecordService;
    @Autowired
    ShopService shopService;
    @Autowired
    RescissionService rescissionService;
    @Autowired
    OrderService orderService;
    @Autowired
    InvitationRecordService invitationRecordService;
    @Autowired
    WalletRecordsService walletRecordsService;
    @Autowired
    DictService dictService;
    @Autowired
    UserService userService;
    @Autowired
    RedisService redisService;
    @Autowired
    ShopWalletService shopWalletService;
    @Autowired
    ShopWalletRecordsService shopWalletRecordsService;
    @Autowired
    ThreadPoolTaskExecutor threadPoolTaskExecutor;
    @Autowired
    ShopCashRecordService shopCashRecordService;
    @Autowired
    ApiCashService apiCashService;


    @RequiresPermissions("sys:check:userCheck")
    @GetMapping("/userCheck")
    String check() {
        return prefix + "/check/userCheck";
    }

    @RequiresPermissions("sys:check:userCheck")
    @GetMapping("/list")
    @ResponseBody()
    PageUtils list(@RequestParam Map<String, Object> params) {
        Query query = new Query(params);

        int count = tUserService.countUserInfo(query);
        if (count > 0) {
            List<TUserInfoVO> userInfo = tUserService.getUserInfo(query);
            logger.error(userInfo.get(0).getCreateDate() + "");
            return new PageUtils(userInfo, count);
        }

        return null;
    }

    @Log("用户保证金审核并创建后台用户账号")
    @RequiresPermissions("sys:check:edit")
    @PostMapping("/wallet")
    @ResponseBody()
    R wallet(WalletDO walletDO) {
        if (walletDO == null || walletDO.getUserId() == null || walletDO.getEnsureAmount() == null) {
            return R.error(1, "操作失败，参数异常");
        }

        TUserDO tUserDO = tUserService.get(walletDO.getUserId());
        if (tUserDO == null) {
            return R.error(1, "该用户信息获取失败");
        }

        if (!Constant.GENERAL_ZERO.equals(tUserDO.getAccountStatus())) {
            return R.error(1, "无效的操作");
        }

        Map<String, Object> map = new HashMap<>(2);
        map.put("userId", walletDO.getUserId());
        List<WalletDO> list = walletService.list(map);
        int count = 0;
        if (CollectionUtils.isEmpty(list)) {
            walletDO.setAmount(new BigDecimal(0));
            walletDO.setFrozenAmount(new BigDecimal(0));
            count = walletService.save(walletDO);
        } else {
            list.get(0).setEnsureAmount(walletDO.getEnsureAmount());
            count = walletService.update(list.get(0));
        }
        if (count == 1) {
            tUserDO.setAccountStatus(Constant.GENERAL_ONE);
            tUserService.update(tUserDO);
        }

        // 创建后台账号
        this.saveDefaultUser(tUserDO.getUserName(), tUserDO.getUserName(), 1);

        return R.error(0, "操作成功");
    }

    @Log("设置用户佣金提成比例")
    @RequiresPermissions("sys:check:edit")
    @PostMapping("/setRatio")
    @ResponseBody()
    R setRatio(WalletDO walletDO) {
        if (walletDO == null || walletDO.getUserId() == null || walletDO.getEnsureAmount() == null) {
            return R.error(1, "操作失败，参数异常");
        }

        TUserDO tUserDO = tUserService.get(walletDO.getUserId());
        if (tUserDO == null) {
            return R.error(1, "用户信息获取失败");
        }

        TUserDO userDO = new TUserDO();
        userDO.setId(tUserDO.getId());
        userDO.setExtraRatio(walletDO.getEnsureAmount() + "");
        tUserService.update(userDO);

        return R.error(0, "操作成功");
    }

    @Log("更新用户状态")
    @RequiresPermissions("sys:check:edit")
    @PostMapping("/update")
    @ResponseBody()
    R update(TUserDO userDO) {
        if (userDO == null || userDO.getId() == null || StringUtils.isBlank(userDO.getAccountStatus())) {
            return R.error(1, "操作失败，参数异常");
        }
        TUserDO tUserDO = tUserService.get(userDO.getId());
        if (tUserDO == null) {
            return R.error(1, "该用户信息获取失败");
        }
        tUserDO.setAccountStatus(userDO.getAccountStatus());
        tUserService.update(tUserDO);
        return R.ok("操作成功");
    }

    /**
     * 商家审核主页
     *
     * @return
     */
    @RequiresPermissions("sys:check:shopCheck")
    @GetMapping("/shopCheck")
    String shopCheck() {
        return prefix + "/check/shopCheck";
    }

    /**
     * 获取商家列表
     *
     * @return
     */
    @RequiresPermissions("sys:check:shopCheck")
    @GetMapping("/shopList")
    @ResponseBody()
    PageUtils shopList(@RequestParam Map<String, Object> params) {
        Query query = new Query(params);

        int count = shopService.count(query);
        List<ShopDO> shopDOS = new ArrayList<>();
        if (count > 0) {
            shopDOS = shopService.list(query);
            if (!CollectionUtils.isEmpty(shopDOS)) {
                for (int i = 0; i < shopDOS.size(); i++) {
                    ShopWalletDO wallet = shopWalletService.getShopWalletByShopId(shopDOS.get(i).getId());
                    if (wallet != null) {
                        shopDOS.get(i).setAmount(wallet.getAmount());
                    }
                }
            }
        }
        return new PageUtils(shopDOS, count);
    }

    @Log("更新商家状态")
    @RequiresPermissions("sys:check:shopEdit")
    @PostMapping("/shopEdit")
    @ResponseBody()
    R shopEdit(ShopDO shopDO) {
        if (shopDO == null || shopDO.getId() == null || StringUtils.isBlank(shopDO.getStatus())) {
            return R.error(1, "操作失败，参数异常");
        }
        ShopDO newShop = shopService.get(shopDO.getId());
        if (newShop == null) {
            return R.error(1, "该商家信息获取失败");
        }


        Map<String, Object> map = new HashMap<>(2);
        map.put("shopId", shopDO.getId());
        List<ShopWalletDO> list = shopWalletService.list(map);
        // 创建商家钱包
        if (CollectionUtils.isEmpty(list)) {
            ShopWalletDO shopWalletDO = new ShopWalletDO();
            shopWalletDO.setAmount(new BigDecimal(0));
            shopWalletDO.setCashFrozen(new BigDecimal(0));
            shopWalletDO.setSysFrozenAmout(new BigDecimal(0));
            shopWalletDO.setShopId(shopDO.getId());
            shopWalletService.save(shopWalletDO);
        }

        if (Constant.GENERAL_ONE.equals(shopDO.getStatus())) {
            // 创建后台账号
            this.saveDefaultUser(newShop.getShopMobile(), newShop.getShopName(), 2);
        }
        newShop.setStatus(shopDO.getStatus());
        shopService.update(newShop);
        return R.ok("操作成功");
    }

    @Log("切换商家汇款二维码显示")
    @RequiresPermissions("sys:check:shopEdit")
    @PostMapping("/cutCode")
    @ResponseBody()
    R cutCode(ShopDO shopDO) {
        if (shopDO == null || shopDO.getId() == null) {
            return R.error(1, "操作失败，参数异常");
        }
        ShopDO newShop = shopService.get(shopDO.getId());
        if (newShop == null) {
            return R.error(1, "该商家信息获取失败");
        }

        if (Constant.GENERAL_ONE.equals(newShop.getRemark())) {
            newShop.setRemark(Constant.GENERAL_ZERO);
        } else {
            newShop.setRemark(Constant.GENERAL_ONE);
        }

        shopService.update(newShop);
        return R.ok("操作成功");
    }

    /**
     * 提现审核主页
     *
     * @return
     */
    @RequiresPermissions("sys:check:cashCheck")
    @GetMapping("/cashCheck")
    String cashCheck() {
        return prefix + "/check/cashCheck";
    }

    /**
     * 获取申请提现列表
     *
     * @return
     */
    @RequiresPermissions("sys:check:cashCheck")
    @GetMapping("/cashList")
    @ResponseBody()
    PageUtils cashList(@RequestParam Map<String, Object> params) {
        Query query = new Query(params);
        int count = cashRecordService.count(query);
        if (count > 0) {
            List<CashRecordDO> cashRecordDOS = cashRecordService.list(query);
            return new PageUtils(cashRecordDOS, count);
        }
        return null;
    }

    @Log("更新提现审核状态")
    @RequiresPermissions("sys:check:cashEdit")
    @PostMapping("/cashEdit")
    @ResponseBody()
    R cashEdit(CashRecordDO cashRecordDO) {
        if (cashRecordDO == null || cashRecordDO.getId() == null || StringUtils.isBlank(cashRecordDO.getStatus())) {
            return R.error(1, "操作失败，参数异常");
        }
        CashRecordDO newShop = cashRecordService.get(cashRecordDO.getId());
        if (newShop == null) {
            return R.error(1, "提现信息获取失败");
        }

        Map<String, Object> params = new HashMap<>(1);
        params.put("userId", newShop.getUserId());
        List<WalletDO> list = walletService.list(params);
        if (CollectionUtils.isEmpty(list)) {
            return R.error(1, "该用户信息异常");
        }

        newShop.setStatus(cashRecordDO.getStatus());
        newShop.setOptId(getUser().getUserId());
        newShop.setOperator(getUser().getUsername());
        newShop.setOptTime(new Date());
        int i = cashRecordService.update(newShop);

        WalletDO walletDO = list.get(0);
        BigDecimal lastAmout = walletDO.getAmount();
        BigDecimal enAmount = walletDO.getFrozenAmount().subtract(newShop.getCashAmount());
        if (i > 0) {
            walletDO.setFrozenAmount(enAmount.compareTo(new BigDecimal(0)) < 0 ? new BigDecimal(0 + "") : enAmount);
        } else {
            return R.ok("未知原因，操作失败");
        }

        if (Constant.GENERAL_TWO.equals(cashRecordDO.getStatus())) {
            walletDO.setFrozenAmount(enAmount.compareTo(new BigDecimal(0)) < 0 ? new BigDecimal(0 + "") : enAmount);
            walletDO.setAmount(walletDO.getAmount().add(newShop.getCashAmount()));
        } else {
            // 记录提现流水
            try {
                threadPoolTaskExecutor.execute(new Runnable() {
                    @Override
                    public void run() {
                        WalletRecordsDO walletRecordsDO = new WalletRecordsDO();
                        walletRecordsDO.setWaterNo(RandomUtils.generateWaterNo());
                        walletRecordsDO.setAmount(newShop.getCashAmount());
                        walletRecordsDO.setUserId(newShop.getUserId());
                        walletRecordsDO.setLastWalletAmount(lastAmout);
                        walletRecordsDO.setWalletAmount(walletDO.getAmount());
                        walletRecordsDO.setType(Constant.GENERAL_ZERO);
                        walletRecordsDO.setSource(Constant.GENERAL_ZERO);
                        walletRecordsService.save(walletRecordsDO);
                    }
                });
            } catch (Exception e) {
                logger.error(e.toString());
            }
        }
        walletService.update(walletDO);

        return R.ok("操作成功");
    }

    /**
     * 解约记录主页
     *
     * @return
     */
    @RequiresPermissions("sys:check:rescCheck")
    @GetMapping("/rescCheck")
    String rescCheck() {
        return prefix + "/check/rescCheck";
    }

    /**
     * 解约记录列表
     *
     * @return
     */
    @RequiresPermissions("sys:check:rescCheck")
    @GetMapping("/rescList")
    @ResponseBody()
    PageUtils rescList(@RequestParam Map<String, Object> params) {
        Query query = new Query(params);
        int count = rescissionService.count(query);
        if (count > 0) {
            List<RescissionDO> rescRecordDOS = rescissionService.list(query);
            return new PageUtils(rescRecordDOS, count);
        }

        return null;
    }

    @Log("更改押金归还状态")
    @RequiresPermissions("sys:check:rescEdit")
    @PostMapping("/rescEdit")
    @ResponseBody()
    R rescEdit(RescissionDO rescRecordDO) {
        if (rescRecordDO == null || rescRecordDO.getId() == null || StringUtils.isBlank(rescRecordDO.getStatus())) {
            return R.error(1, "操作失败，参数异常");
        }
        RescissionDO newShop = rescissionService.get(rescRecordDO.getId());
        if (newShop == null) {
            return R.error(1, "解约记录获取失败");
        }

        newShop.setOptId(getUser().getUserId());
        newShop.setOperator(getUser().getUsername());
        newShop.setOptTime(new Date());
        newShop.setStatus(rescRecordDO.getStatus());
        int update = rescissionService.update(newShop);

        if (update == 1) {
            TUserDO userDO = new TUserDO();
            userDO.setId(newShop.getUserId());
            userDO.setAccountStatus(Constant.GENERAL_THREE);
            tUserService.update(userDO);

            Map<String, Object> params = new HashMap<>(1);
            params.put("userId", newShop.getUserId());
            List<WalletDO> list = walletService.list(params);
            if (!CollectionUtils.isEmpty(list)) {
                list.get(0).setEnsureAmount(new BigDecimal(0));
                walletService.update(list.get(0));
            }
        } else {
            return R.error(1, "操作失败");
        }
        return R.ok("操作成功");
    }

    /**
     * 订单记录主页
     *
     * @return
     */
    @RequiresPermissions("sys:check:orderCheck")
    @GetMapping("/orderCheck")
    String orderCheck() {
        return prefix + "/check/orderCheck";
    }

    /**
     * 订单记录列表
     *
     * @return
     */
    @RequiresPermissions("sys:check:orderCheck")
    @GetMapping("/orderList")
    @ResponseBody()
    PageUtils orderList(@RequestParam Map<String, Object> params) {
        Query query = new Query(params);
//        query.put("sort", "order_status");
//        query.put("order", "DESC");
//        query.put("order_status", "2");

        if (!CollectionUtils.isEmpty(params) && params.containsKey("userName")) {
            String userName = String.valueOf(params.get("userName"));

            if (!StringUtils.isEmpty(userName)) {
                TUserDO user = tUserService.getUserByUserName(userName);
                query.put("userId", user.getId());
            }

            query.remove("userName");
        }

        List<OrderDO> orderDOs = orderService.list(query);
        if (!CollectionUtils.isEmpty(orderDOs)) {
            for (int i = 0; i < orderDOs.size(); i++) {
                if (orderDOs.get(i).getUserId() != null) {
                    TUserDO tUserDO = tUserService.get(orderDOs.get(i).getUserId());
                    if (tUserDO != null) {
                        orderDOs.get(i).setUserName(tUserDO.getUserName());
                    }
                }
                if (orderDOs.get(i).getGameId() != null) {
                    ShopDO shopDO = shopService.get(Long.parseLong(orderDOs.get(i).getGameId()));
                    if (shopDO != null) {
                        orderDOs.get(i).setShopName(shopDO.getShopName());
                    }
                }
            }
        }
        int total = orderService.count(query);
        PageUtils pageUtils = new PageUtils(orderDOs, total);
        return pageUtils;
    }

    @Log("更改订单审核状态")
    @RequiresPermissions("sys:check:orderEdit")
    @PostMapping("/orderEdit")
    @ResponseBody()
    R orderEdit(OrderDO orderDO) {
        if (orderDO == null || orderDO.getOrderId() == null || orderDO.getOrderStatus() == null) {
            return R.error(1, "操作失败，参数异常");
        }

        // 从redis获取控制并发
        Boolean idis = redisService.setNx("orderIdis_" + orderDO.getOrderId(), orderDO.getOrderId() + "", 10L);
        if (idis != null && !idis) {
            return R.error(1, "访问量过大，请10s过后重试");
        }

        OrderDO order = orderService.get(orderDO.getOrderId());
        if (order == null) {
            return R.error(1, "订单记录获取失败");
        }

        if (Constant.GENERAL_ZERO.equals(order.getOrderStatus()) || order.getUserId() == null) {
            return R.error(1, "订单异常");
        }

        // 如果审核通过 发放邀请奖励以及提成奖励 并产生流水
        //  订单状态 0等待接单 1 已接单待付款 2 已付款上传凭证 3审核通过完成 4审核不通过 5申诉中 6订单关闭
        if (Constant.GENERAL_FOUR.equals(orderDO.getOrderStatus() + "")) {
            OrderDO orde = new OrderDO();
            orde.setOrderStatus(orderDO.getOrderStatus());
            orde.setRemark(orderDO.getRemark());
            orde.setOrderId(orderDO.getOrderId());
            orderService.update(orde);
            return R.ok("操作成功");
        } else if (Constant.GENERAL_THREE.equals(orderDO.getOrderStatus() + "")) {
            OrderDO orde = new OrderDO();
            orde.setOrderStatus(orderDO.getOrderStatus());
            orde.setOrderId(orderDO.getOrderId());

            try {
                // 订单奖励发放
                BigDecimal reward = publicReward(Constant.ORDER_REWARD, order.getUserId(), order, Boolean.TRUE);
                orde.setBrokerage(reward);
            } catch (Exception e) {
                logger.error("订单奖励发放异常，订单号：" + order.getOrderId());
                logger.error(e.toString());
                e.printStackTrace();
            }

            try {
                // 邀请人奖励发放
                rewardToInviter(order);
            } catch (Exception e) {
                logger.error("邀请人奖励发放异常，订单号：" + order.getOrderId());
                logger.error(e.toString());
                e.printStackTrace();
            }

            try {
                // 订单商家邀请人奖励
                rewardShopInviter(order);
            } catch (Exception e) {
                logger.error("订单商家邀请人奖励发放异常，订单号：" + order.getOrderId());
                logger.error(e.toString());
            }

            try {
                // 商家结算
                threadPoolTaskExecutor.execute(new Runnable() {
                    @Override
                    public void run() {
                        settleShop(order);
                    }
                });
                orde.setSettle(Constant.GENERAL_ONE);
            } catch (Exception e) {
                orde.setSettle(Constant.GENERAL_ZERO);
                logger.error("订单商家结算异常，订单号：" + order.getOrderId());
                logger.error(e.toString());
            }
            orderService.update(orde);
        } else if (Constant.GENERAL_FIVE.equals(orderDO.getOrderStatus() + "")) {
            // 申诉关闭订单
            OrderDO orde = new OrderDO();
            orde.setOrderStatus(Integer.parseInt(Constant.GENERAL_SIX));
            orde.setOrderId(orderDO.getOrderId());

            Map<String, Object> params = new HashMap<>(3);
            params.put("status", Constant.GENERAL_ONE);
            params.put("orderId", orderDO.getOrderId());
            params.put("userId", orderDO.getUserId());
            try {
                orderService.updateOrderComplaint(params);
            } catch (Exception e) {
                logger.error(e.toString());
            }
            orderService.update(orde);
        } else if (Constant.GENERAL_SIX.equals(orderDO.getOrderStatus() + "")) {
            // 关闭订单
            OrderDO orde = new OrderDO();
            orde.setOrderStatus(Integer.parseInt(Constant.GENERAL_SIX));
            orde.setOrderId(orderDO.getOrderId());
            orderService.update(orde);
        }
        return R.ok("操作成功");
    }

    @Log("订单申诉处理")
    @RequiresPermissions("sys:check:orderEdit")
    @PostMapping("/resetOrder")
    @ResponseBody()
    R resetOrder(OrderDO orderDO) {
        if (orderDO == null || orderDO.getOrderId() == null || orderDO.getOrderStatus() == null) {
            return R.error(1, "操作失败，参数异常");
        }

        OrderDO order = orderService.get(orderDO.getOrderId());
        if (order == null) {
            return R.error(1, "订单记录获取失败");
        }

        Map<String, Object> params = new HashMap<>(3);

        params.put("orderId", order.getOrderId());
        params.put("userId", order.getUserId());

        //  订单状态 0等待接单 1 已接单待付款 2 已付款上传凭证 3审核通过完成 4审核不通过 5申诉中 6订单关闭
        // 申诉关闭订单
        if (Constant.GENERAL_ONE.equals(orderDO.getOrderStatus() + "")) {
            order.setUserId(null);
            order.setPayImg(null);
            order.setBrokerage(null);
            order.setOrderStatus(Integer.parseInt(Constant.GENERAL_ZERO));
            params.put("status", Constant.GENERAL_ONE);
        } else {
            order.setOrderStatus(Integer.parseInt(Constant.GENERAL_SIX));
            params.put("status", Constant.GENERAL_TWO);
        }


        try {
            orderService.updateOrderComplaint(params);
        } catch (Exception e) {
            logger.error(e.toString());
        }
        orderService.updateNoSelective(order);
        return R.ok("操作成功");
    }

    /**
     * 根据订单奖励用户邀请人
     *
     * @param order
     */
    public BigDecimal rewardToInviter(OrderDO order) {
        //  查询邀请人信息
        Map<String, Object> params = new HashMap<>(2);
        params.put("userId", order.getUserId());
        List<InvitationRecordDO> list = invitationRecordService.list(params);
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        BigDecimal reward = publicReward(Constant.INVITER_REWARD, list.get(0).getInviterUserId(), order, Boolean.FALSE);

        try {
            // 记录邀请流水
            saveInviteWater(Constant.INVITER_REWARD, list.get(0).getInviterUserId(), order, reward);
        } catch (Exception e) {
            logger.error("奖励用户邀请人时记录邀请流水异常，订单号：" + order.getOrderId());
            logger.error(e.toString());
            e.printStackTrace();
        }
        return reward;
    }

    /**
     * 订单商家邀请人奖励
     *
     * @param order
     */
    public BigDecimal rewardShopInviter(OrderDO order) {
        ShopDO shopDO = shopService.get(Long.parseLong(order.getGameId()));
        if (shopDO == null) {
            return null;
        }

        if (shopDO.getInviteUserId() == null || shopDO.getInviteUserId() == null) {
            return null;
        }

        BigDecimal reward = publicReward(Constant.SHOP_REWARD, shopDO.getInviteUserId(), order, Boolean.FALSE);

        try {
            // 记录邀请流水
            saveInviteWater(Constant.SHOP_REWARD, shopDO.getInviteUserId(), order, reward);
        } catch (Exception e) {
            logger.error("奖励用户邀请人时记录邀请流水异常，订单号：" + order.getOrderId());
            logger.error(e.toString());
            e.printStackTrace();
        }
        return reward;
    }

    /**
     * 奖励用户
     *
     * @param reward 类型
     * @param userId 要奖励的用户id
     * @param order  订单
     * @return
     */
    private BigDecimal publicReward(String reward, Long userId, OrderDO order, boolean isOwer) {
        Map<String, Object> params = new HashMap<>(1);
        params.put("userId", userId);
        List<WalletDO> walletDOList = walletService.list(params);
        if (!CollectionUtils.isEmpty(walletDOList)) {
            // 获取到配置的奖励比例
            List<DictDO> shop_reward = dictService.listByType(reward);
            if (!CollectionUtils.isEmpty(shop_reward) && StringUtils.isNotBlank(shop_reward.get(0).getValue())
                    && !Constant.GENERAL_ZERO.equals(shop_reward.get(0).getValue())) {
                BigDecimal lastAmount = walletDOList.get(0).getAmount();
                //比例
                BigDecimal ratio = new BigDecimal(shop_reward.get(0).getValue()).setScale(4, BigDecimal.ROUND_HALF_UP);
                // 用户订单佣金 比例计算
                if (Constant.ORDER_REWARD.equals(reward)) {
                    TUserDO tUserDO = tUserService.get(userId);
                    if (tUserDO != null && !StringUtils.isBlank(tUserDO.getExtraRatio())) {
                        ratio = new BigDecimal(tUserDO.getExtraRatio());
                    }
                }

                // 计算奖励金额
                BigDecimal rewardMoney = (ratio.multiply(order.getRealMoney())).setScale(2, BigDecimal.ROUND_HALF_UP);
                WalletDO walletDO = new WalletDO();
                walletDO.setId(walletDOList.get(0).getId());
                if (!isOwer) {
                    walletDO.setAmount(walletDOList.get(0).getAmount().add(rewardMoney));
                }
                walletService.update(walletDO);
                // 插入钱包流水记录
                try {
                    WalletRecordsDO walletRecords = new WalletRecordsDO();
                    walletRecords.setLastWalletAmount(lastAmount);
                    walletRecords.setAmount(rewardMoney);
                    walletRecords.setWalletAmount(walletDO.getAmount());
                    walletRecords.setUserId(order.getUserId());
                    walletRecords.setType(Constant.GENERAL_ONE);
                    walletRecords.setSource(Constant.GENERAL_TWO);
                    walletRecords.setWaterNo(RandomUtils.generateWaterNo());
                    walletRecordsService.save(walletRecords);
                } catch (Exception e) {
                    if (Constant.INVITER_REWARD.equals(reward)) {
                        logger.error("邀请人奖励流水记录异常，订单号：" + order.getOrderId());
                        logger.error(e.toString());
                        e.printStackTrace();
                    } else if (Constant.ORDER_REWARD.equals(reward)) {
                        logger.error("接单提成奖励 流水记录异常，订单号：" + order.getOrderId());
                        logger.error(e.toString());
                        e.printStackTrace();
                    } else if (Constant.SHOP_REWARD.equals(reward)) {
                        logger.error("商家邀请人奖励 流水记录异常，订单号：" + order.getOrderId());
                        logger.error(e.toString());
                        e.printStackTrace();
                    }
                }

                return rewardMoney;
            }
        }
        return null;
    }

    /**
     * 插入邀请流水记录
     *
     * @param reward
     * @param userId
     * @param order
     * @param rewardMoney
     */
    public void saveInviteWater(String reward, Long userId, OrderDO order, BigDecimal rewardMoney) {

        InviteWaterVO inviteWaterVO = new InviteWaterVO();
        inviteWaterVO.setId(userId);
        inviteWaterVO.setUserId(order.getUserId());
        inviteWaterVO.setOrderId(order.getOrderId());
        inviteWaterVO.setShopId(Long.parseLong(order.getGameId()));
        if (Constant.SHOP_REWARD.equals(reward)) {
            inviteWaterVO.setType(Constant.GENERAL_TWO);
        } else {
            inviteWaterVO.setType(Constant.GENERAL_ONE);
        }
        inviteWaterVO.setRewardAmount(rewardMoney);
        walletRecordsService.insertInviteWater(inviteWaterVO);

    }

    /**
     * 生成后台账号
     *
     * @param userName
     * @param status
     */
    public void saveDefaultUser(String userName, String name, int status) {
        Map<String, Object> params = new HashMap<>();
        params.put("username", userName);
        List<UserDO> useDo = userService.list(params);
        if (CollectionUtils.isEmpty(useDo)) {
            // 创建后台账号
            UserDO user = new UserDO();
            String pwd = RandomUtils.generateNumberString(8);
            user.setMobile(userName);
            user.setUsername(userName);
            user.setName(name);
            user.setStatus(1);
            user.setUserIdCreate(getUserId());
            user.setGmtCreate(new Date());
            if (status == 1) {
                user.setRoleIds(Arrays.asList(60L));
                user.setDeptId(12l);
            } else {
                user.setRoleIds(Arrays.asList(61L));
                user.setDeptId(16l);
            }
            user.setPassword(MD5Utils.encrypt(user.getUsername(), pwd));
            userService.save(user);
            // 发送短信告之密码 顺便告诉他审核通过
            try {
                JavaSmsApi.singleSend(MessageFormat.format(Constant.VERIFY_MEDIA, pwd), userName);
            } catch (IOException e) {
                logger.error("发送用户密码短信失败");
            }
        }
    }

    /**
     * 商家订单结算
     *
     * @param order
     */
    public void settleShop(OrderDO order) {
        ShopDO shopDO = shopService.get(Long.parseLong(order.getGameId()));
        if (shopDO == null) {
            return;
        }

        Map<String, Object> params = new HashMap<>(1);
        params.put("orderId", order.getOrderId());
        List<ShopWalletRecordsDO> list = shopWalletRecordsService.list(params);
        if (!CollectionUtils.isEmpty(list)) {
            return;
        }

        //  查询商家钱包信息
        params.put("shopId", shopDO.getId());
        List<ShopWalletDO> shopWalletDOS = shopWalletService.list(params);
        if (CollectionUtils.isEmpty(shopWalletDOS)) {
            return;
        }

        // 查询平台抽成比例
        List<DictDO> sys_reward = dictService.listByType(Constant.SETTLE_ORDER_SHOP);
        if (CollectionUtils.isEmpty(sys_reward) || StringUtils.isBlank(sys_reward.get(0).getValue())) {
            return;
        }

        ShopWalletRecordsDO shopWalletRecordsDO = new ShopWalletRecordsDO();
        // 查询用户提成比例
        TUserDO tUserDO = tUserService.get(order.getUserId());
        if (tUserDO != null && !StringUtils.isBlank(tUserDO.getExtraRatio())) {
            shopWalletRecordsDO.setUserRatio(tUserDO.getExtraRatio());
        } else {
            List<DictDO> user_reward = dictService.listByType(Constant.ORDER_REWARD);
            if (!CollectionUtils.isEmpty(user_reward) && StringUtils.isNotBlank(user_reward.get(0).getValue())) {
                shopWalletRecordsDO.setUserRatio(user_reward.get(0).getValue());
            }
        }

        shopWalletRecordsDO.setWaterNo(RandomUtils.generateWaterNo());
        shopWalletRecordsDO.setOrderId(order.getOrderId());
        shopWalletRecordsDO.setLastWalletAmount(shopWalletDOS.get(0).getAmount());
        shopWalletRecordsDO.setShopId(Long.parseLong(order.getGameId()));
        //来源 0提现 1订单应收
        shopWalletRecordsDO.setSource(Constant.GENERAL_ONE);
        //类型 0支出 1收入
        shopWalletRecordsDO.setType(Constant.GENERAL_ONE);
        shopWalletRecordsDO.setSysRatio(sys_reward.get(0).getValue());
        BigDecimal ratio = new BigDecimal(sys_reward.get(0).getValue()).setScale(4, BigDecimal.ROUND_HALF_UP);
        BigDecimal rewardMoney = (ratio.multiply(order.getRealMoney())).setScale(2, BigDecimal.ROUND_HALF_UP);
        shopWalletRecordsDO.setSysMoney(rewardMoney);
        shopWalletRecordsDO.setAmount(order.getRealMoney().subtract(rewardMoney));
        shopWalletRecordsDO.setUserMoney(order.getBrokerage());


        ShopWalletDO walletDO = shopWalletDOS.get(0);
        walletDO.setAmount(walletDO.getAmount().add(shopWalletRecordsDO.getAmount()));
        int update = shopWalletService.update(walletDO);
        if (update > 0) {
            shopWalletRecordsService.save(shopWalletRecordsDO);
        }
    }

    /**
     * 商家提现页面
     *
     * @return
     */
    @RequiresPermissions("sys:check:shopCashCheck")
    @GetMapping("/shopCashCheck")
    String shopCashCheck() {
        return prefix + "/check/shopCashCheck";
    }

    /**
     * 获取商家申请提现列表
     *
     * @return
     */
    @RequiresPermissions("sys:check:shopCashCheck")
    @GetMapping("/shopCashList")
    @ResponseBody()
    PageUtils shopCashList(@RequestParam Map<String, Object> params) {
        Query query = new Query(params);
        ShopDO shop = null;
        UserDO userDO = userService.get(getUserId());
        if (userDO.getRoleIds().toString().contains("61")) {
            shop = shopService.getShopByShopMobile(getUsername());
            if (shop != null) {
                query.put("shopId", shop.getId());
            } else {
                return null;
            }
        }

        int count = shopCashRecordService.count(params);
        List<ShopCashRecordDO> list = null;
        if (count > 0) {
            list = shopCashRecordService.list(query);
            for (ShopCashRecordDO shopCashRecordDO : list) {
                if (shop == null) {
                    ShopDO shop1 = new ShopDO();
                    shop1 = shopService.get(shopCashRecordDO.getShopId());
                    shopCashRecordDO.setShopName(shop1.getShopName());
                    continue;
                }
                shopCashRecordDO.setShopName(shop.getShopName());
            }
        }

        return new PageUtils(list, count);
    }

    @Log("更新商家提现审核状态")
    @RequiresPermissions("sys:check:shopCashEdit")
    @PostMapping("/shopCashEdit")
    @ResponseBody()
    R shopCashEdit(ShopCashRecordDO cashRecordDO) {
        if (cashRecordDO == null || cashRecordDO.getId() == null
                || StringUtils.isBlank(cashRecordDO.getStatus())) {
            return R.error(1, "操作失败，参数异常");
        }
        ShopCashRecordDO newShop = shopCashRecordService.get(cashRecordDO.getId());
        if (newShop == null) {
            return R.error(1, "提现信息获取失败");
        }

        Map<String, Object> params = new HashMap<>(1);
        params.put("userId", newShop.getShopId());
        List<ShopWalletDO> list = shopWalletService.list(params);
        if (CollectionUtils.isEmpty(list)) {
            return R.error(1, "该商家信息异常");
        }

        newShop.setStatus(cashRecordDO.getStatus());
        newShop.setOptId(getUser().getUserId());
        newShop.setOperator(getUser().getUsername());
        newShop.setOptTime(new Date());
        int i = shopCashRecordService.update(newShop);

        ShopWalletDO walletDO = list.get(0);
        BigDecimal enAmount = walletDO.getCashFrozen().subtract(newShop.getCashAmount());
        if (i > 0) {
            walletDO.setCashFrozen(enAmount.compareTo(new BigDecimal(0)) < 0 ? new BigDecimal(0 + "") : enAmount);
        } else {
            return R.error("操作失败");
        }

        if (Constant.GENERAL_TWO.equals(cashRecordDO.getStatus())) {
            walletDO.setCashFrozen(enAmount.compareTo(new BigDecimal(0)) < 0 ? new BigDecimal(0 + "") : enAmount);
            walletDO.setAmount(walletDO.getAmount().add(newShop.getCashAmount()));
        }
        shopWalletService.update(walletDO);
        return R.ok("操作成功");
    }

    @RequiresPermissions("sys:check:apiCash")
    @GetMapping("/apiCash")
    String apiCash() {
        return prefix + "/apiCash/apiCash";
    }

    @RequiresPermissions("sys:check:apiCash")
    @GetMapping("/uploadVoucher/{id}")
    String uploadVoucher(@PathVariable("id") Long id, Model model) {
        model.addAttribute("id", id);
        return prefix + "/apiCash/edit";
    }

    /**
     * wanjia tixian
     *
     * @param params
     * @return
     */
    @RequiresPermissions("sys:check:apiCash")
    @GetMapping("/apiCashList")
    @ResponseBody()
    PageUtils apiCashList(@RequestParam Map<String, Object> params) {
        Query query = new Query(params);
        UserDO userDO = userService.get(getUserId());
        if (userDO.getRoleIds().toString().contains("61")) {
            ShopDO shop = shopService.getShopByShopMobile(getUsername());
            if (shop != null) {
                query.put("shopId", shop.getId());
            } else {
                return null;
            }
        }

        int count = apiCashService.count(query);
        if (count > 0) {
            query.put("sort", "status asc,");
            query.put("order", "create_time DESC");
            List<ApiCashDO> list = apiCashService.list(query);
            for (ApiCashDO apiCashDO : list) {
                if (apiCashDO.getShopId() != null) {
                    ShopDO shopDO = shopService.get(apiCashDO.getShopId());
                    if (shopDO != null) {
                        apiCashDO.setShopName(shopDO.getShopName());
                    }
                }
            }

            return new PageUtils(list, count);
        }

        return null;
    }

    /**
     * wanjia tixian xiugai zhuangtai
     *
     * @return
     */
    @Log("修改玩家提现状态")
    @RequiresPermissions("sys:check:editApiCash")
    @PostMapping("/editApiCash")
    @ResponseBody()
    R editApiCash(ApiCashDO apiCashDO) {
        if (apiCashDO == null || apiCashDO.getId() == null || StringUtils.isBlank(apiCashDO.getStatus())) {
            return R.error(1, "操作失败，参数异常");
        }

        ApiCashDO apiCashDO1 = apiCashService.get(apiCashDO.getId());

        if (apiCashDO1 == null) {
            return R.error(1, "操作失败");
        }

        Map<String, Object> params = new HashMap<>();
        params.put("source", Constant.GENERAL_TWO);
        params.put("orderId", apiCashDO.getId());
        List<ShopWalletRecordsDO> list = shopWalletRecordsService.list(params);
        if (CollectionUtils.isEmpty(list)) {
            return R.error(1, "操作失败,流水记录异常");
        }
        ShopWalletDO shopWalletByShopId = shopWalletService.getShopWalletByShopId(apiCashDO1.getShopId());
        if (shopWalletByShopId == null) {
            return R.error(1, "操作失败,商家账户异常");
        }
        if (apiCashDO1.getMoney().add(list.get(0).getSysMoney()).compareTo(shopWalletByShopId.getCashFrozen()) < 0) {
            return R.error(1, "操作失败,商家账户冻结记录异常");
        }

        if (Constant.GENERAL_ONE.equals(apiCashDO.getStatus())) {
            // 通过审核  修改冻结状态  扣除冻结金额
            shopWalletByShopId.setCashFrozen(shopWalletByShopId.getCashFrozen().subtract(list.get(0).getAmount().add(list.get(0).getSysMoney())));
            int update = shopWalletService.update(shopWalletByShopId);
        } else if (Constant.GENERAL_TWO.equals(apiCashDO.getStatus())) {
            // 未通过审核  冻结金额还原
            shopWalletByShopId.setCashFrozen(shopWalletByShopId.getCashFrozen().subtract(apiCashDO1.getMoney().add(list.get(0).getSysMoney())));
            shopWalletByShopId.setAmount(shopWalletByShopId.getAmount().add(apiCashDO1.getMoney().add(list.get(0).getSysMoney())));
        }
        int update = shopWalletService.update(shopWalletByShopId);
        if (update == 1) {
            apiCashService.update(apiCashDO);
        }

        return R.ok();
    }
}
